클라이언트 구현하기

Anthropic
Claude에서 열기
이 강좌에 대해 질문하기
노트 복사
LLM용 전체 강좌 노트 복사

MCP 서버가 작동하고 있으니 이제 클라이언트 측을 구축할 차례입니다. 클라이언트는 우리 애플리케이션이 MCP 서버와 통신하고 그 기능에 접근할 수 있게 해주는 역할을 합니다.

클라이언트 아키텍처 이해하기

실제 프로젝트 대부분에서는 MCP 클라이언트 또는 MCP 서버 중 하나만 구현합니다. 이 프로젝트에서는 두 가지가 어떻게 함께 동작하는지 보여주기 위해 둘 다 구축합니다.

MCP 클라이언트는 두 가지 주요 구성 요소로 이루어져 있습니다:

  • MCP Client - 세션을 더 쉽게 사용할 수 있도록 우리가 직접 만드는 커스텀 클래스
  • Client Session - 서버에 대한 실제 연결 (MCP Python SDK의 일부)

클라이언트 세션은 사용이 끝난 후 리소스를 적절히 정리해야 합니다. 그래서 이 정리 작업을 자동으로 처리하기 위해 커스텀 MCP Client 클래스로 감싸는 것입니다.

클라이언트가 애플리케이션에서 차지하는 역할

우리 애플리케이션의 흐름을 기억하시나요? CLI 코드는 MCP 서버와 관련해 두 가지 주요 작업을 수행해야 합니다:

  1. Claude에 전달할 사용 가능한 도구 목록 가져오기
  2. Claude가 요청할 때 도구 실행하기

MCP 클라이언트는 애플리케이션 코드에서 사용할 수 있는 간단한 메서드 호출을 통해 이러한 기능을 제공합니다.

핵심 메서드 구현하기

클라이언트에 두 가지 핵심 메서드를 구현해야 합니다: list_tools()call_tool()입니다.

도구 목록 조회 메서드

이 메서드는 서버에서 사용 가능한 모든 도구를 가져옵니다:

async def list_tools(self) -> list[types.Tool]:
    result = await self.session().list_tools()
    return result.tools

간단합니다. 세션(서버와의 연결)에 접근하여 내장 list_tools() 함수를 호출하고 결과에서 도구 목록을 반환합니다.

도구 호출 메서드

이 메서드는 서버에서 특정 도구를 실행합니다:

async def call_tool(
    self, tool_name: str, tool_input: dict
) -> types.CallToolResult | None:
    return await self.session().call_tool(tool_name, tool_input)

Claude가 제공한 도구 이름과 입력 매개변수를 서버에 전달하고 결과를 반환합니다.

클라이언트 테스트하기

구현을 테스트하려면 클라이언트를 직접 실행할 수 있습니다. 파일에는 MCP 서버에 연결하고 메서드를 호출하는 테스트 코드가 포함되어 있습니다:

async with MCPClient(
    command="uv", args=["run", "mcp_server.py"]
) as client:
    result = await client.list_tools()
    print(result)

이 테스트를 실행하면 앞서 생성한 read_doc_contentsedit_document 도구를 포함한 도구 정의가 출력되는 것을 확인할 수 있습니다.

전체 흐름 통합하기

이제 클라이언트가 도구를 나열하고 호출할 수 있으므로 전체 흐름을 테스트해 볼 수 있습니다. 메인 애플리케이션을 실행하고 Claude에게 문서에 대해 질문하면:

  1. 코드가 클라이언트를 사용해 사용 가능한 도구를 가져옵니다
  2. 이 도구들이 사용자의 질문과 함께 Claude에게 전달됩니다
  3. Claude가 read_doc_contents 도구를 사용하기로 결정합니다
  4. 코드가 클라이언트를 사용해 해당 도구를 실행합니다
  5. 결과가 Claude에게 다시 전달되고, Claude가 사용자에게 응답합니다

예를 들어, "report.pdf 문서의 내용이 무엇인가요?"라고 질문하면 Claude가 문서 읽기 도구를 사용하여 서버에 설정해 둔 20m 응축기 타워 문서에 대한 정보를 반환합니다.

클라이언트는 애플리케이션 로직과 MCP 서버 사이의 다리 역할을 하며, 기반 연결 세부 사항을 신경 쓰지 않고도 서버 기능에 쉽게 접근할 수 있게 해줍니다.